<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="vue.js"></script>
    <script src="vue-router.js"></script>
</head>

<body>
    <div id="app">
        <router-link to="/user/pangchao">pangchao</router-link>
        <router-link to="/user/chaoyue">chaoyue</router-link>
        <router-link to="/foo">foo</router-link>
        <router-view></router-view>
    </div>

    <script>
        'use strict';
        // 钩子方法需要在next下使用，如果直接在钩子下使用，会导致组件无法渲染
        let user = {
            props: ["name"],
            template: '<div> my name is {{ name }} !</div>',
            beforeRouteEnter(to, from, next) {
                // 在渲染该组件的对应路由被 confirm 前调用
                // 不！能！获取组件实例 `this`
                // 因为当守卫执行前，组件实例还没被创建
                next(vm => {
                    //beforeRouteEnter 守卫 不能 访问 this，因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
                    //通过传一个回调给 next来访问组件实例。
                    //在导航被确认的时候执行回调，并且把组件实例作为回调方法的参数。
                    // 通过 `vm` 访问组件实例

                    //tip: 不知道为啥 vm.$data 获取不了数据
                    alert('beforeRouteEnter 被调用！' + vm.$el)
                })
            },
            beforeRouteUpdate(to, from, next) {
                // 在当前路由改变，但是该组件被复用时调用
                // 举例来说，对于一个带有动态参数的路径 /foo/:id，在 /foo/1 和 /foo/2 之间跳转的时候，
                // 由于会渲染同样的 Foo 组件，因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
                // 可以访问组件实例 `this`
                // just use `this`
                // this.name = to.params.name
                alert('beforeRouterUpdate 被调用！' + this.name)
                next()
            },
            beforeRouteLeave(to, from, next) {
                // 导航离开该组件的对应路由时调用
                // 可以访问组件实例 `this`
                // 这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。
                const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
                if (answer) {
                    next()
                } else {
                    next(false)
                }
                alert('beforeRouterLeave 被调用！')
            }
        }

        let foo = {
            template: '<div>foo</div>'
        }
        const router = new VueRouter({
                routes: [{
                    path: '/user/:name',
                    component: user,
                    props: true
                }, {
                    path: '/foo',
                    component: foo
                }]
            })
            /*
                完整的导航解析流程

                1、导航被触发。
                2、在失活的组件里调用离开守卫。
                3、调用全局的 beforeEach 守卫。
                4、在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
                5、在路由配置里调用 beforeEnter。
                6、解析异步路由组件。
                7、在被激活的组件里调用 beforeRouteEnter。
                8、调用全局的 beforeResolve 守卫 (2.5+)。
                9、导航被确认。
                10、调用全局的 afterEach 钩子。
                11、触发 DOM 更新。
                12、用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
        */

        let vm = new Vue({
            data: {
                myText: 'HHHHHH'
            },
            router
        }).$mount('#app')
    </script>
</body>

</html>